说明:本文主要学习guzzlehttp/guzzle package
的使用,该package提供了一套发送HTTP请求API,就像phpunit package, mockery package, symfony package, monolog package, league/filesystem package
一样,是一个经常被使用的package,也是Laravel框架的一个重要依赖之一。AWS SDK for PHP
也是把该package作为一个基础package来使用,以后也想就AWS SDK for PHP
做一些个人分享,对AWS开发感兴趣的可以参看官方文档AWS SDK for PHP,并且AWS提供了官方认证考试:初级开发者证书AWS Certified Developer Associate,高级DevOps工程师证书AWS Certified DevOps Engineer Professional
,感兴趣可以参考官网:AWS Certification。学习Laravel不仅仅需要学习框架的使用和源码,也需要学习这些常用package的使用,这些优秀的package提供了很多代码设计思想和架构概念,这对提高个人设计代码时的能力大有裨益。
本小篇主要学习下Guzzle package
的Stream
概念和使用,如果对Guzzle package
不是很了解可以看下官网Guzzle。
Streams
一次HTTP请求是由起始行、消息头、消息体组成的,消息体(payloads
)可以是很小或者很大,如果使用字符串来存储消息体的话,对于很大的消息体如一个大文件,用字符串存储就会很消耗内存,所以对于大消息体就需要使用Stream来表示。Guzzle使用了\Psr\Http\Message\StreamInterface
来表示该Stream Objects
,该接口也是对PHP Streams的抽象,暴露了一些常用方法:判断stream是否满足要求的方法,isReadable(), isWriable(), isSeekable()
;stream的读写相关操作,read(), write(), close()
;获取元数据方法,getMetadata(), getSize()
;stream操作指针相关方法,rewind(), tell(), eof(), seek()
,等等。
在psr/http-message package中提供了如下接口:\Psr\Http\Message\StreamInterface, \Psr\Http\Message\RequestInterface, \Psr\Http\Message\ServerRequestInterface, \Psr\Http\Message\ResponseInterface, \Psr\Http\Message\MessageInterface, \Psr\Http\Message\UriInterface, \Psr\Http\Message\UploadedFileInterface
。而guzzle/psr7 package提供了这些接口对应的实现:\GuzzleHttp\Psr7\Stream, \GuzzleHttp\Psr7\Request, \GuzzleHttp\Psr7\ServerRequest, \GuzzleHttp\Psr7\Response, \GuzzleHttp\Psr7\Message, \GuzzleHttp\Psr7\Uri, \GuzzleHttp\Psr7\UploadedFile。
本篇主要学习下\GuzzleHttp\Psr7\Stream
相关使用。
Creating Streams
构造一个stream最好方式是使用GuzzleHttp\Psr7\stream_for
,该方法可以接收string, resources from open(), object implements __toString() or Psr\Http\Message\StreamInterface, callables, iterators
,写一个PHPUnit测试看下stream的创建,爆绿灯:
// tests/Guzzle/StreamTest.php
namespace App\Tests\Guzzle;
class StreamTest extends TestCase
{
public function testCreatingStringStream()
{
/** @var \GuzzleHttp\Psr7\Stream $stream */
$stream = \GuzzleHttp\Psr7\stream_for('Laravel is a stream.');
$this->assertEquals('Laravel is a stream.', $stream);
$stream = \GuzzleHttp\Psr7\stream_for('Laravel is a stream.');
$this->assertEquals('Laravel', $stream->read(7));
$this->assertEquals(' is a stream.', $stream->getContents());
$this->assertEquals(true, $stream->eof());
$this->assertEquals(20, $stream->tell());
}
}
// tests/Guzzle/TestCase.php
namespace App\Tests\Guzzle;
use App\Tests\TestCase as BaseCase;
abstract class TestCase extends BaseCase
{
}
还可以把iterator
作为参数来构造stream,PHPUnit测试爆绿灯:
public function testCreatingIteratorStream()
{
$generator = function ($num) {
for ($i = 0; $i < $num; $i++) {
yield 'laravel.';
}
};
$stream = \GuzzleHttp\Psr7\stream_for($generator(3));
$this->assertEquals('laravel.laravel.laravel.', $stream->read(24));
}
还可以把一个resource
作为参数来构造stream,PHPUnit测试爆绿灯:
public function testResourceStreamMetadata()
{
$resource = fopen(storage_path('/logs/laravel.log'), 'r');
$stream = \GuzzleHttp\Psr7\stream_for($resource);
$this->assertEquals(storage_path('/logs/laravel.log'), $stream->getMetadata('uri'));
$this->assertTrue($stream->isReadable());
$this->assertFalse($stream->isWritable());
$this->assertTrue($stream->isSeekable());
}
Stream Decorators
Guzzle
也提供了一些Stream Decorators
来修饰stream handlers,这些Decorators
主要包括以下几种:
AppendStream
BufferStream
CachingStream
DroppingStream
FnStream
InflateStream
LazyOpenStream
LimitStream
NoSeekStream
PumpStream
这里仅仅以\GuzzleHttp\Psr7\AppendStream
为例说明下Stream Decorator
的使用,其他的Decorator可以参考官网。AppendStream
修饰器顾名思义就是可以读取多个stream并拼接成一个stream,PHPUnit测试爆绿灯:
public function testAppendStream()
{
$stream1 = \GuzzleHttp\Psr7\stream_for('Laravel');
$stream2 = \GuzzleHttp\Psr7\stream_for(' is ');
$stream3 = \GuzzleHttp\Psr7\stream_for('great!!!');
$append_stream = new \GuzzleHttp\Psr7\AppendStream([$stream1, $stream2]);
$append_stream->addStream($stream3);
$this->assertEquals('Laravel is great!!!', $append_stream);
}
总结:学习Guzzle Package的使用是必要的,该package经常作为一个重要依赖被其他package使用,比如AWS SDK for PHP就严重使用该package来做HTTP请求。后续还会分享Guzzle Package相关使用,到时见。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。